# Server

Rsbuild comes with a built-in dev server designed to improve the development experience. When you run the `rsbuild dev` or `rsbuild preview` commands, the server will start, providing features such as page preview, routing, and hot module reloading.

## Page Routing

Rsbuild Server offers a set of default routing convention, and allows users to customize it through configurations.

### Default Behavior

Rsbuild Server will generate the corresponding page route based on the [source.entry](/config/source/entry) configuration.

When entry is index, the page can be accessed through `/`; when entry is foo, the page can be accessed through `/foo`.

```ts title=rsbuild.config.ts
export default {
  source: {
    entry: {
      index: './src/index.ts',
      foo: './src/pages/foo/index.ts',
    },
  },
};
```

### Fallback Behavior

By default, when the request meets the following conditions and the corresponding resource is not found, it will fallback to `index.html`:

- The request is a `GET` or `HEAD` request
- Which accepts `text/html` (the request header accept type is `text/html` or `*/*`)

```ts title=rsbuild.config.ts
export default {
  server: {
    htmlFallback: 'index',
  },
};
```

### Custom Fallback Behavior

When Rsbuild's default [server.htmlFallback](/config/server/html-fallback) configuration cannot meet your needs, for example, if you want to be able to access `main.html` when accessing `/`, you can set it up using [server.historyApiFallback](/config/server/history-api-fallback).

```ts title=rsbuild.config.ts
export default {
  source: {
    entry: {
      main: './src/index.ts',
    },
  },
  server: {
    htmlFallback: false,
    historyApiFallback: {
      index: '/main.html',
    },
  },
};
```

### HTML Output Path

Normally, `/` points to the dist root directory, and the HTML file is output to the dist root directory. At this time, the corresponding HTML page can be accessed through `/some-path`.

If you output HTML files to other subdirectories by modifying [output.distPath.html](/config/output/dist-path), you need to access the corresponding HTML page through `/[htmlPath]/some-path`.

For example, if you set the HTML file to be output to the `HTML` directory, index.html will be accessed through `/html/`, and foo.html will be accessed through `/html/foo`.

```ts
export default {
  source: {
    entry: {
      index: './src/index.ts',
      foo: './src/pages/foo/index.ts',
    },
  },
  output: {
    distPath: {
      html: 'html',
    },
  },
};
```

## Rspack Dev Server

The built-in dev server of Rspack CLI is [@rspack/dev-server](https://www.npmjs.com/package/@rspack/dev-server). Rsbuild does not use `@rspack/dev-server`, but implements a lighter version based on [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware).

### Comparison

The dev server of Rsbuild and `@rspack/dev-server` have the following differences:

- **Configuration**: Rsbuild provides richer server configuration options.
- **Log Format**: The log format of Rspack CLI is basically consistent with Webpack CLI, while Rsbuild's logs are clearer and more readable.
- **Dependencies**: `@rspack/dev-server` is based on express with many third-party dependencies. Rsbuild, on the other hand, uses lighter libraries such as `connect`.

### Configuration

Rsbuild does not support using Rspack's [devServer](https://rspack.dev/config/dev-server) config. Instead, you can use Rsbuild's `dev` and `server` configs.

In Rsbuild, `dev` contains some configs that are only work during development, while the `server` config works for both dev and preview servers.

Below are the Rsbuild configs that correspond to the Rspack CLI's `devServer` config:

| Rspack CLI                                                                                       | Rsbuild                                                          |
| ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| [devServer.client](https://rspack.dev/config/dev-server#devserverclient)                         | [dev.client](/config/dev/client)                                 |
| [devServer.compress](https://rspack.dev/config/dev-server#devservercompress)                     | [server.compress](/config/server/compress)                       |
| [devServer.headers](https://rspack.dev/config/dev-server#devserverheaders)                       | [server.headers](/config/server/headers)                         |
| [devServer.historyApiFallback](https://rspack.dev/config/dev-server#devserverhistoryapifallback) | [server.historyApiFallback](/config/server/history-api-fallback) |
| [devServer.host](https://rspack.dev/config/dev-server#devserverhost)                             | [server.host](/config/server/host)                               |
| [devServer.hot](https://rspack.dev/config/dev-server#devserverhot)                               | [dev.hmr](/config/dev/hmr)                                       |
| [devServer.liveReload](https://rspack.dev/config/dev-server#devserverlivereload)                 | [dev.liveReload](/config/dev/live-reload)                        |
| [devServer.open](https://rspack.dev/config/dev-server#devserveropen)                             | [server.open](/config/server/open)                               |
| [devServer.port](https://rspack.dev/config/dev-server#devserverport)                             | [server.port](/config/server/port)                               |
| [devServer.proxy](https://rspack.dev/config/dev-server#devserverproxy)                           | [server.proxy](/config/server/proxy)                             |
| [devServer.setupMiddlewares](https://rspack.dev/config/dev-server#devserversetupmiddlewares)     | [dev.setupMiddlewares](/config/dev/setup-middlewares)            |
| [devServer.static](https://rspack.dev/config/dev-server#devserverstatic)                         | [server.publicDir](/config/server/public-dir)                    |
| [devServer.watchFiles](https://rspack.dev/config/dev-server#devserverwatchfiles)                 | [dev.watchFiles](/config/dev/watch-files)                        |

> For more configurations, please refer to [Config Overview](/config/index).

## Extend middleware

Rsbuild server does not use any Node.js frameworks, and the `req` and `res` provided by Rsbuild middleware are both native Node.js objects.

This means that when you migrate from other server-side frameworks (such as Express), the original middleware may not necessarily be used directly in Rsbuild. For example, the `req.params`,`req.path`, `req.search`, `req.query` and other properties provided by Express cannot be accessed in the Rsbuild middleware.

If you need to use existing middleware in Rsbuild, this can be done by passing the server application as middleware as follows:

```ts title="rsbuild.config.ts"
import expressMiddleware from 'my-express-middleware';
import express from 'express';

// Initialize Express app
const app = express();

app.use(expressMiddleware);

export default {
  dev: {
    setupMiddlewares: [
      (middleware) => {
        middleware.unshift(app);
      },
    ],
  },
};
```

## Custom Server

If you want to integrate Rsbuild dev server into a custom server, you can get the instance methods of Rsbuild dev server through the `createDevServer` method of Rsbuild and call them on demand.

For details, please refer to [Rsbuild - createDevServer](/api/javascript-api/instance#rsbuildcreatedevserver).
